package com.qike.duola.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.qike.duola.domain.*;
import com.qike.duola.dto.*;
import com.qike.duola.enums.*;
import com.qike.duola.mapper.*;
import com.qike.duola.service.ApprovalService;
import com.qike.duola.service.DuolaContractService;
import com.qike.duola.service.DuolaTransOrderService;
import com.qike.duola.utils.StringUtil;
import com.qike.duola.utils.TimeTool;
import com.qike.duola.vo.*;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: Eric.zhou
 * @Date: 2020/9/2 15:10
 */
@Service
public class DuolaContractServiceImpl implements DuolaContractService {

    private static final Logger logger = LoggerFactory.getLogger(DuolaContractServiceImpl.class);
    @Autowired
    private DuolaQuoteMapper duolaQuoteMapper;

    @Autowired
    private DuolaQuotePayMapper duolaQuotePayMapper;
    @Autowired
    private DuolaProjectMapper duolaProjectMapper;
    @Autowired
    private DuolaContractMapper duolaContractMapper;
    @Autowired
    private DuolaTransOrderService transOrderService;
    @Autowired
    private DuolaCustomerMapper duolaCustomerMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private ApprovalService approvalService;


    /**
     * 添加合同
     *
     * @param contractAddDto
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void contractAdd(ContractAddDto contractAddDto) throws Exception {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "添加了合同" + JSON.toJSON(contractAddDto));
        approvalService.findProcess(ApprovalOrderTypeEnums.CONTRACT.getEcode());
        DuolaContractWithBLOBs contract = new DuolaContractWithBLOBs();
        contract.setAddTime(LocalDateTime.now());
        contract.setAddUid(userId);
        contract.setProjectId(contractAddDto.getProjectId());
        contract.setContractLevel(contractAddDto.getLevel());
        contract.setContractType(contractAddDto.getContractType());
        contract.setContractName(contractAddDto.getName());
        contract.setTitle(contractAddDto.getTitle());
        contract.setSaleId(contractAddDto.getSaleId());
        contract.setContractPhone(contractAddDto.getPhone());
        contract.setContractNum(contractAddDto.getContractNum());
        contract.setCustomerId(contractAddDto.getCustomerId());
        contract.setEndTime(TimeTool.LongToLocalDateTime(contractAddDto.getEndTime()));
        contract.setStartTime(TimeTool.LongToLocalDateTime(contractAddDto.getStartTime()));
        contract.setTotalPrice(contractAddDto.getTotalPrice());
        contract.setTotalVolume(contractAddDto.getTotalVolume());
        contract.setQuoteId(contractAddDto.getQuoteId());
        contract.setPayType(contractAddDto.getPayId());
        contract.setRemark(contractAddDto.getRemark());
        contract.setPhoto(contractAddDto.getPhoto());
        contract.setStatus(StatusEnums.NO.getEcode());
        contract.setOrderStatus(ContractStatusEnums.UN_PRODUCT.getEcode());
        contract.setExamineStatus(ExamineEnums.EXAMINE_ING.getEcode());
        duolaContractMapper.insertSelective(contract);
        DuolaQuote duolaQuote = duolaQuoteMapper.selectByPrimaryKey(contractAddDto.getQuoteId());
        if (duolaQuote!=null){
            duolaQuote.setContractId(contract.getId());
            duolaQuoteMapper.updateByPrimaryKeySelective(duolaQuote);
        }
        //绑定报价单绑定合同id
//         todo 发起审批
        try {
            approvalService.startApproval(userId,contract.getId(),ApprovalOrderTypeEnums.CONTRACT.getEcode());
        } catch (Exception e) {
           throw e;
        }


    }

    /**
     * 合同列表
     *
     * @param contractListDto
     * @return
     */
    @Override
    public ContractListVo contractList(ContractListDto contractListDto) {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "查看合同列表" + JSON.toJSON(contractListDto));
        ContractListVo vo = new ContractListVo();
        List<ContractList> list = new ArrayList<>();

        DuolaContractExample example = new DuolaContractExample();
        DuolaContractExample.Criteria criteria = example.createCriteria();
        //客户id
        if (contractListDto.getCustomerId() != null) {
            criteria.andCustomerIdEqualTo(contractListDto.getCustomerId());
        }
        //联系人
        if (!StringUtils.isEmpty(contractListDto.getName())) {
            criteria.andContractNameEqualTo(contractListDto.getName());
        }
        //合同类型
        if (contractListDto.getContractType() != null) {
            criteria.andContractTypeEqualTo(contractListDto.getContractType());
        }
        //联系电话
        if (!StringUtils.isEmpty(contractListDto.getPhone())) {
            criteria.andContractPhoneEqualTo(contractListDto.getPhone());
        }
        //审核状态
        if (contractListDto.getExamineStatus() != null) {
            criteria.andExamineStatusEqualTo(contractListDto.getExamineStatus());
        }
        criteria.andStatusEqualTo(StatusEnums.NO.getEcode()).andParentIdIsNull();
        example.setOrderByClause("add_time desc");
        Page page = PageHelper.startPage(contractListDto.getStartPage(), contractListDto.getPageSize());
        List<DuolaContractWithBLOBs> duolaContractWithBLOBs = duolaContractMapper.selectByExampleWithBLOBs(example);
        for (DuolaContractWithBLOBs duolaContractWithBLOB : duolaContractWithBLOBs) {
            integrationContractList(duolaContractWithBLOB, list);
        }
        vo.setList(list);
        vo.setTotal(page.getTotal());
        return vo;
    }

    /**
     * 合同详情
     *
     * @param id
     * @return
     */
    @Override
    public ContractInfoVo contractInfo(Integer id) throws Exception {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "查看合同详情" + JSON.toJSON(id));
        DuolaContractWithBLOBs duolaContractWithBLOBs = duolaContractMapper.selectByPrimaryKey(id);
        if (duolaContractWithBLOBs == null) {
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }
        ContractInfoVo vo = new ContractInfoVo();
        vo.setId(duolaContractWithBLOBs.getId());
        vo.setRemark(duolaContractWithBLOBs.getRemark());
        vo.setAddTime(TimeTool.LocalDateTimeFormat(duolaContractWithBLOBs.getAddTime()));
        vo.setEndTime(TimeTool.LocalDateTimeFormat(duolaContractWithBLOBs.getEndTime()));
        DuolaCustomer duolaCustomer = duolaCustomerMapper.selectByPrimaryKey(duolaContractWithBLOBs.getCustomerId());
        if (duolaCustomer != null) {
            vo.setName(duolaCustomer.getContractName());
        }
        vo.setPhoto(duolaContractWithBLOBs.getPhoto());
        StringBuilder photoNames = new StringBuilder();
        if (!StringUtils.isEmpty(duolaContractWithBLOBs.getPhoto())) {
            for (String urls : duolaContractWithBLOBs.getPhoto().split(",")) {
                photoNames.append("," + urls.substring(urls.lastIndexOf("/") + 1));
            }
            vo.setPhotoName(photoNames.toString());
        }

        vo.setPhone(duolaContractWithBLOBs.getContractPhone());
        SysUserWithBLOBs sysUserWithBLOBs = sysUserMapper.selectByPrimaryKey(duolaContractWithBLOBs.getSaleId());
        if (sysUserWithBLOBs != null) {
            vo.setSaleName(sysUserWithBLOBs.getNickname());
        }
        vo.setAddTime(TimeTool.LocalDateTimeFormat(duolaContractWithBLOBs.getAddTime()));
        vo.setExamineStatus(duolaContractWithBLOBs.getExamineStatus());
        vo.setExamineStatusStr(ExamineEnums.statOf(duolaContractWithBLOBs.getExamineStatus()).getEmsg());
        vo.setCustomerId(duolaContractWithBLOBs.getCustomerId());
        vo.setCustomerName(duolaCustomer.getCustomerName());
        vo.setContractNum(duolaContractWithBLOBs.getContractNum());
        vo.setContractLevel(duolaContractWithBLOBs.getContractLevel());
        vo.setContractTitle(duolaContractWithBLOBs.getTitle());
        vo.setContractType(duolaContractWithBLOBs.getContractType());
        vo.setContractTypeStr(ContractTypeEnums.statOf(duolaContractWithBLOBs.getContractType()).getEmsg());
        vo.setContractStatus(duolaContractWithBLOBs.getOrderStatus());
        vo.setContractStatusStr(ContractStatusEnums.statOf(duolaContractWithBLOBs.getOrderStatus()).getEmsg());
        vo.setProjectId(duolaContractWithBLOBs.getProjectId());
        DuolaProject duolaProject = duolaProjectMapper.selectByPrimaryKey(duolaContractWithBLOBs.getProjectId());
        if (duolaProject != null) {
            vo.setProjectName(duolaProject.getProjectName());
        }
        vo.setStartTime(TimeTool.LocalDateTimeFormatNoTime(duolaContractWithBLOBs.getStartTime()));
        vo.setEndTime(TimeTool.LocalDateTimeFormatNoTime(duolaContractWithBLOBs.getEndTime()));
        vo.setTotalPrice(duolaContractWithBLOBs.getTotalPrice());
        vo.setTotalVolume(duolaContractWithBLOBs.getTotalVolume());
        vo.setQuoteId(duolaContractWithBLOBs.getQuoteId());
        if (duolaContractWithBLOBs.getQuoteId() != null) {
            DuolaQuote duolaQuote = duolaQuoteMapper.selectByPrimaryKey(duolaContractWithBLOBs.getQuoteId());
            if (duolaQuote != null) {
                vo.setQuoteId(duolaQuote.getId());
                vo.setQuoteName(duolaQuote.getQuoteNum());
                vo.setQuotePayId(duolaContractWithBLOBs.getPayType());
                vo.setQuotePayName(PayTypeEnums.statOf(duolaContractWithBLOBs.getPayType()).getEmsg());
            }
        }
        //todo 获取已结金额
        vo.setFinishPrice(BigDecimal.ZERO);
        vo.setSendVolume(transOrderService.getSendVolumeByProjectId(duolaContractWithBLOBs.getProjectId()));
        return vo;
    }

    /**
     * 转正
     *
     * @param transFormalDto
     */
    @Override
    public void transFormal(TransFormalDto transFormalDto) throws Exception {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "转正合同" + JSON.toJSON(transFormalDto));
        DuolaContractWithBLOBs duolaContractWithBLOBs = duolaContractMapper.selectByPrimaryKey(transFormalDto.getId());
        if (duolaContractWithBLOBs == null) {
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }
        if (duolaContractWithBLOBs.getContractType().equals(ContractTypeEnums.TEMPORARY_CONTRACT.getEcode())) {
            duolaContractWithBLOBs.setContractType(ContractTypeEnums.CONTRACT.getEcode());
            duolaContractWithBLOBs.setPhoto(duolaContractWithBLOBs.getPhoto() + "," + transFormalDto.getPhoto());
            duolaContractMapper.updateByPrimaryKeyWithBLOBs(duolaContractWithBLOBs);
        }

    }

    /**
     * 添加补充协议
     *
     * @param addSupplementaryAgreementDto
     */
    @Override
    public void addSupplementaryAgreement(AddSupplementaryAgreementDto addSupplementaryAgreementDto) throws Exception {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "添加补充协议" + JSON.toJSON(addSupplementaryAgreementDto));
        approvalService.findProcess(ApprovalOrderTypeEnums.QUOTE.getEcode());
//        查找合同
        DuolaContractWithBLOBs duolaContractWithBLOBs = duolaContractMapper.selectByPrimaryKey(addSupplementaryAgreementDto.getContractId());
        if (duolaContractWithBLOBs == null) {
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }

        //查询该合同最新的报价单
//        DuolaQuoteExample duolaQuoteExample = new DuolaQuoteExample();
//        duolaQuoteExample.createCriteria().andStatusEqualTo(StatusEnums.NO.getEcode()).andContractIdEqualTo(duolaContractWithBLOBs.getId());
//        List<DuolaQuote> duolaQuotes = duolaQuoteMapper.selectByExample(duolaQuoteExample);
//        //最新的报价单
//        DuolaQuote firstQuote = duolaQuotes.get(0);
        // 创建报价单
        DuolaQuote duolaQuote = new DuolaQuote();
        duolaQuote.setPercentage(addSupplementaryAgreementDto.getPercentage());
        duolaQuote.setDays(addSupplementaryAgreementDto.getDays());
        duolaQuote.setIsOther(StatusEnums.NO.getEcode());
        duolaQuote.setStatus(StatusEnums.NO.getEcode());
        duolaQuote.setProjectId(duolaContractWithBLOBs.getProjectId());
        duolaQuote.setAddUid(userId);
        duolaQuote.setCustomerId(duolaContractWithBLOBs.getCustomerId());
        duolaQuote.setContractName(duolaContractWithBLOBs.getContractName());
        duolaQuote.setContractPhone(duolaContractWithBLOBs.getContractPhone());
        duolaQuote.setTitle("合同"+duolaContractWithBLOBs.getTitle()+"的补充协议");
        duolaQuote.setSaleId(duolaContractWithBLOBs.getSaleId());
        duolaQuote.setAddTime(LocalDateTime.now());
        duolaQuote.setStartTime(TimeTool.LongToLocalDateTime(addSupplementaryAgreementDto.getStartTime()));
        duolaQuote.setEndTime(duolaContractWithBLOBs.getEndTime());
        duolaQuote.setExamineStatus(ExamineEnums.EXAMINE_ING.getEcode());
        duolaQuoteMapper.insertSelective(duolaQuote);
        DuolaContractWithBLOBs duolaContract = new DuolaContractWithBLOBs();
        duolaContract.setQuoteId(duolaQuote.getId());
        duolaContract.setParentId(addSupplementaryAgreementDto.getContractId());
        duolaContract.setAddTime(LocalDateTime.now());
        duolaContract.setAddUid(userId);
        duolaContract.setPayType(duolaContractWithBLOBs.getPayType());
        duolaContract.setStatus(StatusEnums.NO.getEcode());
        duolaContract.setContractType(ContractTypeEnums.SUPPLEMENTARY_AGREEMENT.getEcode());
        duolaContract.setCustomerId(duolaContractWithBLOBs.getCustomerId());
        duolaContract.setContractName(duolaContractWithBLOBs.getContractName());
        duolaContract.setSaleId(duolaContractWithBLOBs.getSaleId());
        duolaContract.setContractPhone(duolaContractWithBLOBs.getContractPhone());
        duolaContract.setStartTime(TimeTool.LongToLocalDateTime(addSupplementaryAgreementDto.getStartTime()));
        duolaContract.setEndTime(duolaContractWithBLOBs.getEndTime());
        duolaContract.setExamineStatus(ExamineEnums.EXAMINE_ING.getEcode());
        duolaContract.setPhoto(addSupplementaryAgreementDto.getPhoto());
        duolaContract.setRemark(addSupplementaryAgreementDto.getRemark());
        duolaContract.setContractNum(addSupplementaryAgreementDto.getContractNum());
        duolaContractMapper.insertSelective(duolaContract);
        // 添加结算方式
        for (PayTypeDto payTypeDto : addSupplementaryAgreementDto.getList()) {
            for (PayTypeGoodsDto payTypeGoodsDto : payTypeDto.getList()) {
                DuolaQuotePay duolaQuotePay = new DuolaQuotePay();
                duolaQuotePay.setGoodsName(payTypeGoodsDto.getGoodsName());
                duolaQuotePay.setGoodsPrice(payTypeGoodsDto.getGoodsPrice());
                duolaQuotePay.setAddTime(LocalDateTime.now());
                duolaQuotePay.setQuoteId(duolaQuote.getId());
                duolaQuotePay.setStatus(StatusEnums.NO.getEcode());
                duolaQuotePay.setPayType(payTypeDto.getPayType());
                duolaQuotePayMapper.insertSelective(duolaQuotePay);
            }
        }
        //         todo 发起审批
        approvalService.startApproval(userId,duolaQuote.getId(),ApprovalOrderTypeEnums.QUOTE.getEcode());
    }

    /**
     * 查看补充协议
     *
     * @param id
     * @return
     */
    @Override
    public SupplementaryAgreementInfoVo supplementaryAgreementInfo(Integer id) throws Exception {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "查看补充协议" + JSON.toJSON(id));
        //查询合同 补充协议
        DuolaContractWithBLOBs duolaContractWithBLOBs = duolaContractMapper.selectByPrimaryKey(id);
        if (duolaContractWithBLOBs == null) {
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }
        List<SupplementaryAgreementInfoGoodsVo> list = new ArrayList<>();

        SupplementaryAgreementInfoVo vo = new SupplementaryAgreementInfoVo();
        vo.setPayType(duolaContractWithBLOBs.getPayType());
        if (duolaContractWithBLOBs.getPayType().equals(PayTypeEnums.MONTH_PERCENTAGE.getEcode())){
            DuolaQuote duolaQuote = duolaQuoteMapper.selectByPrimaryKey(duolaContractWithBLOBs.getQuoteId());
            vo.setPayTypeStr(StringUtil.contractString(duolaQuote.getPercentage(),duolaQuote.getDays()));
        }else {
            vo.setPayTypeStr(PayTypeEnums.statOf(duolaContractWithBLOBs.getPayType()).getEmsg());
        }
        vo.setPhoto(duolaContractWithBLOBs.getPhoto());
        vo.setRemark(duolaContractWithBLOBs.getRemark());
        vo.setContractNum(duolaContractWithBLOBs.getContractNum());
        vo.setStartTime(TimeTool.LocalDateTimeFormat(duolaContractWithBLOBs.getStartTime()));
        vo.setQuoteId(duolaContractWithBLOBs.getQuoteId());
        DuolaQuotePayExample example = new DuolaQuotePayExample();
        example.createCriteria().andQuoteIdEqualTo(duolaContractWithBLOBs.getQuoteId());
        List<DuolaQuotePay> duolaQuotePays = duolaQuotePayMapper.selectByExample(example);
        for (DuolaQuotePay duolaQuotePay : duolaQuotePays) {
            SupplementaryAgreementInfoGoodsVo goodsVo = new SupplementaryAgreementInfoGoodsVo();
//            goodsVo.setGoodsId(duolaQuotePay.getGoodsId());
            goodsVo.setId(duolaQuotePay.getId());
            goodsVo.setGoodsName(duolaQuotePay.getGoodsName());
            goodsVo.setGoodsId(duolaQuotePay.getGoodsId());
            goodsVo.setPrice(duolaQuotePay.getGoodsPrice());
            list.add(goodsVo);
        }
        vo.setList(list);
        return vo;
    }

    /**
     * 编辑合同
     *
     * @param contractEditDto
     */
    @Override
    public void contractEdit(ContractEditDto contractEditDto) throws Exception {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
//        logger.info(userId+"编辑合同"+ JSON.toJSON(contractEditDto));
        approvalService.findProcess(ApprovalOrderTypeEnums.CONTRACT.getEcode());
        DuolaContractWithBLOBs duolaContractWithBLOBs = duolaContractMapper.selectByPrimaryKey(contractEditDto.getId());
        if (duolaContractWithBLOBs == null) {
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }
        if (!duolaContractWithBLOBs.getExamineStatus().equals(ExamineEnums.EXAMINE_REFUSE.getEcode())) {
            throw new Exception(ErrorEnums.ERROR_UPDATE.getEmsg());
        }
        DuolaContractWithBLOBs contract = duolaContractWithBLOBs;
        contract.setUpdateTime(LocalDateTime.now());
        contract.setUpdateId(userId);
        contract.setProjectId(contractEditDto.getProjectId());
        contract.setContractLevel(contractEditDto.getLevel());
        contract.setContractType(contractEditDto.getContractType());
        contract.setContractName(contractEditDto.getName());
        contract.setTitle(contractEditDto.getTitle());
        contract.setSaleId(contractEditDto.getSaleId());
        contract.setContractPhone(contractEditDto.getPhone());
        contract.setContractNum(contractEditDto.getContractNum());
        contract.setCustomerId(contractEditDto.getCustomerId());
        contract.setEndTime(TimeTool.LongToLocalDateTime(contractEditDto.getEndTime()));
        contract.setStartTime(TimeTool.LongToLocalDateTime(contractEditDto.getStartTime()));
        contract.setTotalPrice(contractEditDto.getTotalPrice());
        contract.setTotalVolume(contractEditDto.getTotalVolume());
        contract.setQuoteId(contractEditDto.getQuoteId());
        contract.setPayType(contractEditDto.getPayId());
        contract.setRemark(contractEditDto.getRemark());
        contract.setPhoto(contractEditDto.getPhoto());
        contract.setExamineStatus(ExamineEnums.EXAMINE_ING.getEcode());
        duolaContractMapper.updateByPrimaryKeyWithBLOBs(contract);
        //todo 发起审批
        approvalService.startApproval(userId,contract.getId(),ApprovalOrderTypeEnums.CONTRACT.getEcode());
    }

    /**
     * 删除合同
     *
     * @param contractDelDto
     */
    @Override
    public void contractDel(ContractDelDto contractDelDto) throws Exception {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "删除合同" + JSON.toJSON(contractDelDto));
        DuolaContractWithBLOBs duolaContractWithBLOBs = duolaContractMapper.selectByPrimaryKey(contractDelDto.getId());
        if (duolaContractWithBLOBs == null) {
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }
        if (!duolaContractWithBLOBs.getExamineStatus().equals(ExamineEnums.EXAMINE_REFUSE.getEcode())) {
            throw new Exception(ErrorEnums.ERROR_UPDATE.getEmsg());
        }
        duolaContractWithBLOBs.setStatus(StatusEnums.YES.getEcode());
        duolaContractMapper.updateByPrimaryKeyWithBLOBs(duolaContractWithBLOBs);
    }

    /**
     * 获取某个客户下所有已审批的合同下工程列表
     *
     * @param uid
     * @return
     */
    @Override
    public List<DuolaProject> GetProjectListByUid(Integer uid) {
        List<DuolaProject> duolaProjects = new ArrayList<>();
        List<Integer> projectIds = new ArrayList<>();
        DuolaContractExample contractExample = new DuolaContractExample();
        contractExample.createCriteria().andExamineStatusEqualTo(ExamineEnums.EXAMINE_SUCCESS.getEcode()).andCustomerIdEqualTo(uid);
        List<DuolaContract> duolaContracts = duolaContractMapper.selectByExample(contractExample);
        for (DuolaContract duolaContract : duolaContracts) {
            projectIds.add(duolaContract.getProjectId());
        }
        if (projectIds.size() > 0) {
            DuolaProjectExample projectExample = new DuolaProjectExample();
            projectExample.createCriteria().andIdIn(projectIds).andStatusEqualTo(StatusEnums.NO.getEcode());
            duolaProjects = duolaProjectMapper.selectByExample(projectExample);
        }
        return duolaProjects;
    }

    /**
     * 开始/停止供货
     *
     * @param startOrStopDto
     */
    @Override
    public void startOrStop(StartOrStopDto startOrStopDto) throws Exception {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "开始/停止供货" + JSON.toJSON(startOrStopDto));
        DuolaContractWithBLOBs duolaContractWithBLOBs = duolaContractMapper.selectByPrimaryKey(startOrStopDto.getId());
        if (duolaContractWithBLOBs == null) {
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }
        duolaContractWithBLOBs.setOrderStatus(startOrStopDto.getOrderStatus());
        duolaContractWithBLOBs.setUpdateId(userId);
        duolaContractWithBLOBs.setUpdateTime(LocalDateTime.now());
        duolaContractMapper.updateByPrimaryKeyWithBLOBs(duolaContractWithBLOBs);
    }

    /**
     * 根据合同id获取已绑定报价单的详细列表
     *
     * @param id
     * @return
     */
    @Override
    public List<PayGoodsListByQuoteIdVo> getQuoteByContractId(Integer id) throws Exception {
        //根据合同id获取已绑定的报价单
        DuolaContractWithBLOBs duolaContractWithBLOBs = duolaContractMapper.selectByPrimaryKey(id);
        if (duolaContractWithBLOBs == null) {
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }
        Integer quoteId = duolaContractWithBLOBs.getQuoteId();
        DuolaQuote duolaQuote = duolaQuoteMapper.selectByPrimaryKey(quoteId);
        Integer payType = duolaContractWithBLOBs.getPayType();
        List<PayGoodsListByQuoteIdVo> list = new ArrayList<>();
        Map<Integer, List<PayGoodsListByQuoteId>> goodsMap = new HashMap<>();
        //根据报价单id查询商品
        DuolaQuotePayExample example = new DuolaQuotePayExample();
        example.createCriteria().andQuoteIdEqualTo(quoteId).andPayTypeEqualTo(payType);
        List<DuolaQuotePay> duolaQuotePays = duolaQuotePayMapper.selectByExample(example);
        for (DuolaQuotePay duolaQuotePay : duolaQuotePays) {
            PayGoodsListByQuoteId payGoodsListByQuoteId = new PayGoodsListByQuoteId();
            payGoodsListByQuoteId.setId(duolaQuotePay.getId());
            payGoodsListByQuoteId.setGoodsId(duolaQuotePay.getGoodsId());
            payGoodsListByQuoteId.setGoodsName(duolaQuotePay.getGoodsName());
            payGoodsListByQuoteId.setGoodsPrice(duolaQuotePay.getGoodsPrice());
            List<PayGoodsListByQuoteId> payGoodsListByQuoteIds = goodsMap.get(duolaQuotePay.getPayType());
            if (payGoodsListByQuoteIds == null) {
                payGoodsListByQuoteIds = new ArrayList<>();
            }
            payGoodsListByQuoteIds.add(payGoodsListByQuoteId);
            goodsMap.put(duolaQuotePay.getPayType(), payGoodsListByQuoteIds);
        }
        for (Map.Entry<Integer, List<PayGoodsListByQuoteId>> integerListEntry : goodsMap.entrySet()) {
            PayGoodsListByQuoteIdVo vo = new PayGoodsListByQuoteIdVo();
            vo.setPayType(integerListEntry.getKey());
            if(integerListEntry.getKey().equals(PayTypeEnums.MONTH_PERCENTAGE.getEcode())){
                vo.setPayTypeName(StringUtil.contractString(duolaQuote.getPercentage(),duolaQuote.getDays()));
            }else {
                vo.setPayTypeName(PayTypeEnums.statOf(integerListEntry.getKey()).getEmsg());
            }
            vo.setGoodsList(integerListEntry.getValue());
            list.add(vo);
        }
        return list;
    }


    /**
     * 获取合同子级
     *
     * @param parentId
     * @return
     */
    private List<ContractList> contractGetChild(Integer parentId) {
        List<ContractList> lists = new ArrayList<>();
        DuolaContractExample example = new DuolaContractExample();
        example.setOrderByClause("add_time desc");
        example.createCriteria().andParentIdEqualTo(parentId).andStatusEqualTo(StatusEnums.NO.getEcode()).andContractTypeEqualTo(ContractTypeEnums.SUPPLEMENTARY_AGREEMENT.getEcode());
        List<DuolaContractWithBLOBs> duolaContractWithBLOBs = duolaContractMapper.selectByExampleWithBLOBs(example);
        for (DuolaContractWithBLOBs duolaContractWithBLOB : duolaContractWithBLOBs) {
            lists = integrationContractList(duolaContractWithBLOB, lists);
//            lists.add(chilidList);
        }
        return lists;


    }

    /**
     * 提取合同列表的方法
     *
     * @param duolaContractWithBLOB
     * @param lists
     */
    @Override
    public List<ContractList> integrationContractList(DuolaContractWithBLOBs duolaContractWithBLOB, List<ContractList> lists) {
        ContractList contractList = new ContractList();
        contractList.setContractNum(duolaContractWithBLOB.getContractNum());
        contractList.setContractStatus(duolaContractWithBLOB.getOrderStatus());
        if (duolaContractWithBLOB.getOrderStatus() != null) {
            contractList.setContractStatusStr(ContractStatusEnums.statOf(duolaContractWithBLOB.getOrderStatus()).getEmsg());
        }
        contractList.setContractType(duolaContractWithBLOB.getContractType());
        contractList.setContractTypeStr(ContractTypeEnums.statOf(duolaContractWithBLOB.getContractType()).getEmsg());
        contractList.setId(duolaContractWithBLOB.getId());
        contractList.setParentId(duolaContractWithBLOB.getParentId());
        contractList.setStartTime(TimeTool.LocalDateTimeFormat(duolaContractWithBLOB.getStartTime()));
        contractList.setEndTime(TimeTool.LocalDateTimeFormat(duolaContractWithBLOB.getEndTime()));
        DuolaCustomer duolaCustomer = duolaCustomerMapper.selectByPrimaryKey(duolaContractWithBLOB.getCustomerId());
        if (duolaCustomer != null) {
            contractList.setName(duolaCustomer.getCustomerName());
        }
        contractList.setPhone(duolaContractWithBLOB.getContractPhone());
        SysUserWithBLOBs sysUserWithBLOBs = sysUserMapper.selectByPrimaryKey(duolaContractWithBLOB.getSaleId());
        if (sysUserWithBLOBs != null) {
            contractList.setSaleName(sysUserWithBLOBs.getNickname());
        }
//            contractList.setContractStatus(duolaContractWithBLOB.getOrderStatus());
//            contractList.setContractStatusStr(ContractStatusEnums.statOf(duolaContractWithBLOB.getOrderStatus()).getEmsg());
        contractList.setAddTime(TimeTool.LocalDateTimeFormat(duolaContractWithBLOB.getAddTime()));
        contractList.setExamineStatus(duolaContractWithBLOB.getExamineStatus());
        contractList.setExamineStatusStr(ExamineEnums.statOf(duolaContractWithBLOB.getExamineStatus()).getEmsg());
        if (duolaContractWithBLOB.getContractType() != ContractTypeEnums.SUPPLEMENTARY_AGREEMENT.getEcode()) {
            contractList.setChild(contractGetChild(duolaContractWithBLOB.getId()));
        }
        contractList.setProjectId(duolaContractWithBLOB.getProjectId());
        DuolaProject duolaProject = duolaProjectMapper.selectByPrimaryKey(duolaContractWithBLOB.getProjectId());
        if (duolaProject != null) {
            contractList.setProjectName(duolaProject.getProjectName());
        }
        lists.add(contractList);
        return lists;
    }

    /**
     * 编辑补充协议
     *
     * @param editSupplementaryAgreementDto
     */
    @Override
    public void editSupplementaryAgreement(EditSupplementaryAgreementDto editSupplementaryAgreementDto) throws Exception {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "添加补充协议" + JSON.toJSON(editSupplementaryAgreementDto));
        approvalService.findProcess(ApprovalOrderTypeEnums.QUOTE.getEcode());
//        查找合同
        DuolaContractWithBLOBs duolaContractWithBLOBs = duolaContractMapper.selectByPrimaryKey(editSupplementaryAgreementDto.getContractId());
        if (duolaContractWithBLOBs == null) {
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }


        //查询报价单
        Integer quoteId = duolaContractWithBLOBs.getQuoteId();
        DuolaQuote duolaQuote = duolaQuoteMapper.selectByPrimaryKey(quoteId);
        duolaQuote.setPercentage(editSupplementaryAgreementDto.getPercentage());
        duolaQuote.setDays(editSupplementaryAgreementDto.getDays());
        duolaQuote.setIsOther(StatusEnums.NO.getEcode());
        duolaQuote.setStatus(StatusEnums.NO.getEcode());
        duolaQuote.setProjectId(duolaContractWithBLOBs.getProjectId());
        duolaQuote.setAddUid(userId);
        duolaQuote.setCustomerId(duolaContractWithBLOBs.getCustomerId());
        duolaQuote.setContractName(duolaContractWithBLOBs.getContractName());
        duolaQuote.setContractPhone(duolaContractWithBLOBs.getContractPhone());
        duolaQuote.setTitle("合同"+duolaContractWithBLOBs.getTitle()+"的补充协议");
        duolaQuote.setSaleId(duolaContractWithBLOBs.getSaleId());
        duolaQuote.setAddTime(LocalDateTime.now());
        duolaQuote.setStartTime(TimeTool.LongToLocalDateTime(editSupplementaryAgreementDto.getStartTime()));
        duolaQuote.setEndTime(duolaContractWithBLOBs.getEndTime());
        duolaQuote.setExamineStatus(ExamineEnums.EXAMINE_ING.getEcode());
        duolaQuoteMapper.updateByPrimaryKeySelective(duolaQuote);


        DuolaContractWithBLOBs duolaContract = duolaContractMapper.selectByPrimaryKey(editSupplementaryAgreementDto.getId());
        duolaContract.setQuoteId(duolaQuote.getId());
        duolaContract.setParentId(editSupplementaryAgreementDto.getContractId());
        duolaContract.setAddTime(LocalDateTime.now());
        duolaContract.setAddUid(userId);
        duolaContract.setPayType(duolaContractWithBLOBs.getPayType());
        duolaContract.setStatus(StatusEnums.NO.getEcode());
        duolaContract.setContractType(ContractTypeEnums.SUPPLEMENTARY_AGREEMENT.getEcode());
        duolaContract.setCustomerId(duolaContractWithBLOBs.getCustomerId());
        duolaContract.setContractName(duolaContractWithBLOBs.getContractName());
        duolaContract.setSaleId(duolaContractWithBLOBs.getSaleId());
        duolaContract.setContractPhone(duolaContractWithBLOBs.getContractPhone());
        duolaContract.setStartTime(TimeTool.LongToLocalDateTime(editSupplementaryAgreementDto.getStartTime()));
        duolaContract.setEndTime(duolaContractWithBLOBs.getEndTime());
        duolaContract.setExamineStatus(ExamineEnums.EXAMINE_ING.getEcode());
        duolaContract.setPhoto(editSupplementaryAgreementDto.getPhoto());
        duolaContract.setRemark(editSupplementaryAgreementDto.getRemark());
        duolaContract.setContractNum(editSupplementaryAgreementDto.getContractNum());
        duolaContractMapper.insertSelective(duolaContract);
        // 添加结算方式
        for (PayTypeDto payTypeDto : editSupplementaryAgreementDto.getList()) {
            for (PayTypeGoodsDto payTypeGoodsDto : payTypeDto.getList()) {
                DuolaQuotePay duolaQuotePay = new DuolaQuotePay();
                duolaQuotePay.setId(payTypeGoodsDto.getId());
                duolaQuotePay.setGoodsName(payTypeGoodsDto.getGoodsName());
                duolaQuotePay.setGoodsPrice(payTypeGoodsDto.getGoodsPrice());
                duolaQuotePay.setAddTime(LocalDateTime.now());
                duolaQuotePay.setQuoteId(duolaQuote.getId());
                duolaQuotePay.setStatus(StatusEnums.NO.getEcode());
                duolaQuotePay.setPayType(payTypeDto.getPayType());
                duolaQuotePayMapper.updateByPrimaryKeySelective(duolaQuotePay);
            }
        }
        //         todo 发起审批
        approvalService.startApproval(userId,duolaQuote.getId(),ApprovalOrderTypeEnums.QUOTE.getEcode());
    }
}

